{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "calling __init__ method\n",
      "clalling __enter__ method\n",
      "ready to write file\n",
      "clalling __exit__ method\n"
     ]
    }
   ],
   "source": [
    "# 上下文管理器\n",
    "class FileManager:\n",
    "    def __init__(self,name,mode):\n",
    "        print('calling __init__ method')\n",
    "        self.name = name\n",
    "        self.mode = mode\n",
    "        self.file = None\n",
    "    def __enter__(self):\n",
    "        print('clalling __enter__ method')\n",
    "        self.file = open(self.name,self.mode)\n",
    "        return self.file\n",
    "    def __exit__(self,exc_type,exc_vale,exc_tb):\n",
    "        print('clalling __exit__ method')\n",
    "        if self.file:\n",
    "            self.file.close()\n",
    "with FileManager('test.txt','w') as f:\n",
    "    print('ready to write file')\n",
    "    f.write('hello word')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "calling __init__ method\n",
      "clalling __enter__ method\n",
      "clalling __exit__ method\n",
      "exc_type: <class 'Exception'>\n",
      "exc_value: Exception raised\n",
      "exc_tb: <traceback object at 0x000001BF613DB140>\n"
     ]
    }
   ],
   "source": [
    "# 上下文管理器\n",
    "class Foo:\n",
    "    def __init__(self):\n",
    "        print('calling __init__ method')\n",
    "    def __enter__(self):\n",
    "        print('clalling __enter__ method')\n",
    "        return self\n",
    "    def __exit__(self,exc_type,exc_value,exc_tb):\n",
    "        print('clalling __exit__ method')\n",
    "        if exc_type:\n",
    "            print(f'exc_type: {exc_type}')\n",
    "            print(f'exc_value: {exc_value}')\n",
    "            print(f'exc_tb: {exc_tb}')\n",
    "        return True\n",
    "# with FileManager('test.txt','w') as f:\n",
    "#     print('ready to write file')\n",
    "#     f.write('hello word')\n",
    "with Foo() as obj:\n",
    "    raise Exception('Exception raised').with_traceback(None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据库连接使用上下文管理器\n",
    "class DBConnectionManager:\n",
    "    def __init__(self,hostname,port):\n",
    "        self.hostname = hostname\n",
    "        self.port = port\n",
    "        self.connection = None\n",
    "    def __enter__(self):\n",
    "        self.connection = DBClient(self.hostname,self.port)\n",
    "        return self.connection\n",
    "    def __exit__(self,exec_type,exec_value,exec_tb):\n",
    "        self.connection.close()\n",
    "with DBConnectionManager('localhost','8080') as db_client:\n",
    "    db_client"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 使用注解实现上下文管理器\n",
    "from contextlib import contextmanager\n",
    "@contextmanager\n",
    "def file_manager(name,mode):\n",
    "    try:\n",
    "        f = open(name,mode=mode)\n",
    "        yield f\n",
    "    finally:\n",
    "        f.close()\n",
    "with file_manager('test.txt','w') as f:\n",
    "    f.write('Hello world V!')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
